package com.songlanyun.modules.order.service.impl.createorder;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.http.Header;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.songlanyun.common.enums.HouniaoConstant;
import com.songlanyun.common.enums.IntegralConstant;
import com.songlanyun.common.enums.OrderConstant;
import com.songlanyun.common.exception.RRException;
import com.songlanyun.common.utils.HouniaoApiUtil;
import com.songlanyun.common.utils.StrUtil;
import com.songlanyun.common.utils.custom.MathUtils;
import com.songlanyun.modules.account.entity.UserIdentityAssetEntity;
import com.songlanyun.modules.account.service.AccountService;
import com.songlanyun.modules.account.service.UserIdentityAssetService;
import com.songlanyun.modules.account.service.UserServiceAreaTemporaryService;
import com.songlanyun.modules.account.service.impl.UserVerifiedServiceImpl;
import com.songlanyun.modules.exception.GoodsExceptionEnum;
import com.songlanyun.modules.goods.entity.Goods;
import com.songlanyun.modules.goods.entity.GoodsSku;
import com.songlanyun.modules.goods.service.GoodsService;
import com.songlanyun.modules.goods.service.GoodsSkuService;
import com.songlanyun.modules.integralrecord.service.IntegralRecordService;
import com.songlanyun.modules.inter.ISaleEntity;
import com.songlanyun.modules.marketing.firstorder.entity.FirstOrderActivity;
import com.songlanyun.modules.marketing.firstorder.service.FirstOrderActivityService;
import com.songlanyun.modules.memberbill.entity.GiveBalanceDTO;
import com.songlanyun.modules.order.dao.OrderDao;
import com.songlanyun.modules.order.entity.Order;
import com.songlanyun.modules.order.model.dto.HouniaoCheckDTO;
import com.songlanyun.modules.order.model.dto.SubmitChildOrderDTO;
import com.songlanyun.modules.order.model.dto.SubmitOrderDTO;
import com.songlanyun.modules.order.model.dto.SubmitShopOrderDTO;
import com.songlanyun.modules.order.model.vo.SubmitChildOrderVo;
import com.songlanyun.modules.order.model.vo.SubmitOrderReceiptVo;
import com.songlanyun.modules.order.model.vo.SubmitOrderVo;
import com.songlanyun.modules.order.model.vo.SubmitShopOrderVo;
import com.songlanyun.modules.order.service.ChildOrderService;
import com.songlanyun.modules.order.service.CreateOrderService;
import com.songlanyun.modules.order.service.OrderService;
import com.songlanyun.modules.order.service.impl.coupon.platformcoupon.IUsePlatformCouponService;
import com.songlanyun.modules.order.service.impl.coupon.shopcoupon.IUseShopCouponService;
import com.songlanyun.modules.order.service.impl.platformpoin.IUsePlatformPoint;
import com.songlanyun.modules.payorder.entity.PayOrder;
import com.songlanyun.modules.payorder.service.PayOrderService;
import com.songlanyun.modules.saleconfig.service.SaleConfigService;
import com.songlanyun.modules.singlegoods.entity.ProductSingleGoodsEntity;
import com.songlanyun.modules.user.exception.UserException;
import org.apache.commons.lang.StringUtils;
import org.checkerframework.checker.units.qual.K;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.math.RoundingMode;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


/**
 * 普通商品订单构单与下单
 */
@Service("commonCreateOrderService")
public class CommonCreateOrderServiceImpl extends ServiceImpl<OrderDao, Order> implements CreateOrderService {

    @Resource(name="createOrderService")
    private CreateOrderService createOrderService;

    @Autowired
    private GoodsService goodsService;

    @Autowired
    private GoodsSkuService goodsSkuService;
    @Autowired
    private PayOrderService payOrderService;

    @Autowired
    private ChildOrderService childOrderService;

    @Autowired
    private OrderService orderService;

    @Autowired
    private SaleConfigService saleConfigService;

    @Autowired
    private FirstOrderActivityService firstOrderActivityService;

    @Autowired
    private UserIdentityAssetService userIdentityAssetService;

    @Autowired
    private IntegralRecordService integralRecordService;


    @Resource(name = "commonOrderUseShopCouponService")
    private IUseShopCouponService commonOrderUseShopCouponService;

    @Resource(name = "firstOrderUseShopCouponService")
    private IUseShopCouponService firstOrderUseShopCouponService;

    @Resource(name = "commonOrderUsePlatformCouponService")
    private IUsePlatformCouponService commonOrderUsePlatformCouponService;


    @Resource(name = "commonOrderUsePlatformPoint")
    private IUsePlatformPoint commonOrderUsePlatformPoint;


    @Autowired
    private UserServiceAreaTemporaryService userServiceAreaTemporaryService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private HouniaoApiUtil houniaoApiUtil;

    @Autowired
    private UserVerifiedServiceImpl userVerifiedServiceImpl;



    /**
     * 构建下单页数据
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    public SubmitOrderVo buildSubmitOrder(Long userId, SubmitOrderDTO dto) {


        validateGoods(userId,dto);
        SubmitOrderVo vo = initSubmitOrderVo(userId, dto);

        // 候鸟商品渲染
//        validateHouniaoGoods(vo);

        List<SubmitShopOrderVo> shopOrderVoList = commonOrderBuild(userId, vo, dto);
        BigDecimal totalMoneyNoFreight = MathUtils.setScale(shopOrderVoList.stream().mapToDouble(c -> c.getTotalAmountNoFreight().doubleValue()).sum());
        BigDecimal totalMoney = MathUtils.setScale(shopOrderVoList.stream().mapToDouble(c -> c.getTotalAmount().doubleValue()).sum());
        BigDecimal totalReducedMoney = MathUtils.setScale(shopOrderVoList.stream().mapToDouble(c -> c.getTotalReduced().doubleValue()).sum());
        BigDecimal totalAmountDecShopCoupon = MathUtils.setScale(shopOrderVoList.stream().mapToDouble(c -> c.getTotalAmountDecShopCoupon().doubleValue()).sum());

        vo.setShopOrders(shopOrderVoList);
        vo.setTotalAmountDecShopCoupon(totalAmountDecShopCoupon);
        vo.setTotalMoneyNoFreight(totalMoneyNoFreight);
        vo.setTotalReduced(totalReducedMoney);
        vo.setTotalMoney(totalMoney);
        vo.setAreaFeature(vo.getShopOrders().get(0).getAreaFeature());



//        /**
//         * 1、先在在里计算推荐使用或选择使用的平台优惠券
//         * 2、分摊给给店铺订单
//         * 3、再分摊给店铺订单的商品子订单
//         */
//        commonOrderUsePlatformCouponService.handlePlatformCoupon(userId,vo);
//        if(vo.getPlatformCoupon().getCouponId()>0) {
//            vo.setTotalMoneyNoFreight(MathUtils.subtract(vo.getTotalMoneyNoFreight(),vo.getPlatformCoupon().getCouponResultValue()));
//            vo.setTotalMoney(MathUtils.subtract(vo.getTotalMoney(),vo.getPlatformCoupon().getCouponResultValue()));
//            vo.setTotalReduced(MathUtils.add(vo.getTotalReduced(),vo.getPlatformCoupon().getCouponResultValue()));
//        }
//
//        if(dto.getUsePlatformPoint()) {
//            BigDecimal platformPoint = commonOrderUsePlatformPoint.handle(vo);
//            if (platformPoint.compareTo(BigDecimal.ZERO) > 0) {
//                vo.setTotalPoint(platformPoint);
//                vo.setTotalMoneyNoFreight(MathUtils.subtract(vo.getTotalMoneyNoFreight(), platformPoint));
//                vo.setTotalMoney(MathUtils.subtract(vo.getTotalMoney(), platformPoint));
//                vo.setTotalReduced(MathUtils.add(vo.getTotalReduced(), platformPoint));
//            }
//        }
//        else
//        {
//            UserIdentityAssetEntity asset = userIdentityAssetService.getById(vo.getUserId(), true);
//            vo.setIntegralAble(asset.getIntegralAble());
//        }

        UserIdentityAssetEntity asset = userIdentityAssetService.getById(vo.getUserId(), true);
        vo.setIntegralAble(asset.getIntegralAble());
        vo.setPointEnough(true);
        return vo;
    }



    /**
     * 会员下单服务
     *
     * @param userId
     * @param dto
     * @return
     */

    @Override
    public PayOrder createPayOrder(Long userId, SubmitOrderDTO dto) {
        /**
         * 构建下单数据
         */
        SubmitOrderVo submitOrderVo = buildSubmitOrder(userId, dto);
        if (!dto.getIsAdminOrder()){
            thirdCanSaleCheck(submitOrderVo);
        }

        /**
         * 提取商品图片为了待支付订单
         */
        List<String> goodsImages = new ArrayList<>();
        submitOrderVo.getShopOrders().forEach(o -> {
            o.getItems().forEach(c -> {
                goodsImages.add(c.getGoodsCover());
            });
        });

        long expiredTimestamp = saleConfigService.getExpiredTimestamp();
        /**
         * 创建支付订单（1，用来做合单，2用来做支付）
         */
        PayOrder payOrder = null;
        if(submitOrderVo.getTotalPoint().compareTo(BigDecimal.ZERO)>0) {
            payOrder = payOrderService.initPayOrderForSaleAndPoint(userId, submitOrderVo.getTotalMoney(), submitOrderVo.getTotalReduced(),submitOrderVo.getTotalPoint(), OrderConstant.PayMode.POINT_BALANCE, OrderConstant.OrderType.SALE_ORDER, goodsImages, expiredTimestamp,submitOrderVo.getPlatformCoupon(),submitOrderVo.getAreaFeature());
        }
        else
        {
            payOrder = payOrderService.initPayOrderForSale(userId, submitOrderVo.getTotalMoney(), submitOrderVo.getTotalReduced(), OrderConstant.PayMode.BALANCE, OrderConstant.OrderType.SALE_ORDER, goodsImages, expiredTimestamp,submitOrderVo.getPlatformCoupon(),submitOrderVo.getAreaFeature());
        }
        List<SubmitShopOrderVo> shopOrders = submitOrderVo.getShopOrders();
        for (SubmitShopOrderVo shopOrder : shopOrders) {
            /**
             * 开始创建商家订单
             */
            // 需要实名信息的订单进行存库
            payOrder.setRealName(dto.getRealName());
            payOrder.setIdNo(dto.getIdNo());
            Order order = createOrder(userId, payOrder, submitOrderVo, shopOrder);

            if(order.getTotalPoint().compareTo(BigDecimal.ZERO)>0) {
                integralRecordService.outer(order.getUserId(), order.getTotalPoint(),
                        IntegralConstant.OuterMode.POINT_PLATFORM, IntegralConstant.IntegralModelType.ORDER, order.getId(),
                        String.format("平台公益积分抵扣订单[%s]扣除积分:%.2f", order.getOrderCode(), order.getTotalPoint()));
            }
            /**
             * 创建收货地址或自提信息
             */
            if (!dto.getIsAdminOrder()){
                createOrderReceiving(order, submitOrderVo);
            }
            /**
             * 创建订单的钥匙
             */
            createOrderKey(order);
            List<SubmitChildOrderVo> items = shopOrder.getItems();
            for (SubmitChildOrderVo childOrderVo : items) {
                /**
                 * 创建订单的商品子订单明细
                 */
                childOrderService.create(order, childOrderVo);
            }

            if(order.getServiceSystemGoods())
            {
                if(CollectionUtil.isEmpty(dto.getSelectAreas()))
                {
                    throw new RRException("购买服务体系商品必须选择地区");
                }
                userServiceAreaTemporaryService.updateServiceArea(userId,dto.getSelectAreas());
            }
        }

        return payOrder;
    }

    @Override
    public void thirdCanSaleCheck(SubmitOrderVo vo) {
        createOrderService.thirdCanSaleCheck(vo);
    }

    /**
     * 校验候鸟商品
     */
    private void validateHouniaoGoods(SubmitOrderVo vo) {
        for(SubmitShopOrderVo submitShopOrderVo:vo.getShopOrders()) {
            if (submitShopOrderVo.getThird() && 99 == submitShopOrderVo.getSource()) {
                List<HouniaoCheckDTO> list = new ArrayList<>();
                List<SubmitChildOrderVo> items = submitShopOrderVo.getItems();
                items.forEach( item -> {
                    HouniaoCheckDTO houniaoCheckDTO = new HouniaoCheckDTO();
                    houniaoCheckDTO.setGoods_num(item.getNum());
                    houniaoCheckDTO.setSku_id(String.valueOf(item.getThirdSkuId()));
                    houniaoCheckDTO.setGoods_spu(item.getHouniaoSpuId());
                    list.add(houniaoCheckDTO);
                });
                JSONArray jsonArray = new JSONArray();

                list.forEach( item -> {
                    JSONObject js = JSON.parseObject(JSONObject.toJSONString(item));
                    js = houniaoApiUtil.sortJsonObject(js);
                    jsonArray.add(js);
                });

                JSONObject checkGoods = new JSONObject();
                checkGoods.put("area_id", vo.getReceipt().getAreaCode());
                checkGoods.put("order_goods", jsonArray);

                JSONObject checkGoodsRes = houniaoApiUtil.client(checkGoods, HouniaoConstant.CHECK_GOODS_ORDER_BATCH.getUrl());
                log.debug("商品渲染" + checkGoodsRes.toJSONString());

                if (200 != checkGoodsRes.getInteger("code")) {
                    throw new RRException("可售检测：商品不可下单");
                }
            }
        }
    }

    /**
     * 校验普通商品
     *
     * @param userId
     * @param dto
     */
    private void validateGoods(Long userId, SubmitOrderDTO dto) {
        Map<Long, Integer> goodsCountMap = new HashMap<>();

        dto.getShopOrders().forEach(sso -> {
            Map<Long, Integer> goodsMap = sso.getItems().stream().collect(Collectors.groupingBy(SubmitChildOrderDTO::getGoodsId, Collectors.summingInt(SubmitChildOrderDTO::getNum)));
            HashMap<String, Boolean> typeMap = new HashMap<>(2);
            typeMap.put("isCommon",false);
            typeMap.put("isThird",false);
            goodsMap.forEach((key, value) -> {
                Goods goods = goodsService.getById(key, true);
                if(goods.getThird())
                {
                    typeMap.put("isThird",true);
                }
                else
                {
                    typeMap.put("isCommon",true);
                }
                if (goodsCountMap.containsKey(key)) {
                    goodsCountMap.put(key, goodsCountMap.get(key) + value);
                } else {
                    goodsCountMap.put(key, value);
                }
            });
            if(typeMap.get("isCommon") && typeMap.get("isThird"))
            {
                throw new RRException("本地商品与第三方商品不能混合购买");
            }
        });

        goodsCountMap.forEach((goodsId, buyNum) -> {
            //普通商品限购
            Goods goods = goodsService.getById(goodsId, true);
            if (goods.getLimitBuyNum() > 0) {
                String goodsTitle = StrUtil.truncation(goods.getTitle(), 10);
                if (buyNum > goods.getLimitBuyNum()) {
                    throw new RRException("[" + goodsTitle + "],每人限购" + goods.getLimitBuyNum() + "件",GoodsExceptionEnum.GOODS_LIMIT_BUY.getCode());
                } else {
                    Integer buyGoodsCount = childOrderService.getBuyGoodsCount(userId, goodsId, 0);
                    if (buyGoodsCount + buyNum > goods.getLimitBuyNum()) {
                        throw new RRException("[" + goodsTitle + "],每人限购" + goods.getLimitBuyNum() + "件",GoodsExceptionEnum.GOODS_LIMIT_BUY.getCode());
                    }
                }
            }
        });
    }

    /**
     * 内部调用初始化订单的基础数据================================================
     *
     * @param userId
     * @param dto
     * @return
     */
    @Override
    public SubmitOrderVo initSubmitOrderVo(Long userId, SubmitOrderDTO dto) {
        return createOrderService.initSubmitOrderVo(userId,dto);
    }


    /**
     * 内部调用 重构初始化构造提交商家订单vo
     *
     * @param userId
     * @param dto
     * @param o
     * @return
     */
    @Override
    public SubmitShopOrderVo initBuildSubmitShopOrderVo(Long userId, SubmitOrderDTO dto, SubmitShopOrderDTO o) {
        return createOrderService.initBuildSubmitShopOrderVo(userId,dto,o);
    }

    /**
     * 内部调用 重构初始化构造提交商家子订单vo
     *
     * @param saleEntity
     * @param dto
     * @param o
     * @param s
     * @return
     */
    @Override
    public SubmitChildOrderVo initBuildSubmitChildOrderVo(ISaleEntity saleEntity, SubmitOrderDTO dto, SubmitShopOrderDTO o, SubmitChildOrderDTO s) {
        return createOrderService.initBuildSubmitChildOrderVo(saleEntity,dto,o,s);
    }

    @Override
    public void computeSelectedShopCoupon(Long userId, SubmitShopOrderVo vo, SubmitShopOrderDTO o) {
         createOrderService.computeSelectedShopCoupon(userId,vo,o);
    }

    @Override
    public void backStageManagement(GiveBalanceDTO dto) {

    }


    /**
     * 普通订单构单
     * 这里默认候鸟为一个商店,app逻辑中候鸟第三方与自营商品无法同时下单,候鸟订单进来不会做循环,
     * @param userId
     * @param vo
     * @param dto
     * @return
     */
    private List<SubmitShopOrderVo> commonOrderBuild(Long userId, SubmitOrderVo vo, SubmitOrderDTO dto) {
        return dto.getShopOrders().stream().map(o -> {

            SubmitShopOrderVo shopOrderVo = initBuildSubmitShopOrderVo(userId, dto, o);
            //如果是普通订单
            shopOrderVo.setSponsorActivityId(0L);
            shopOrderVo.setActivityId(0L);
            shopOrderVo.setActivityTitle("");
            if(shopOrderVo.getPlatformShop())
            {
                vo.setHasPlatform(true);
            }

            // 候鸟商品统计

            JSONArray houniaoGoods = new JSONArray();

            //产品税费数组
            List<BigDecimal> shui = new ArrayList<>();

            List<SubmitChildOrderVo> childOrderVoList = o.getItems().stream().map(s -> {
                Goods goods = goodsService.getByShopIdAndId(o.getShopId(), s.getGoodsId());
                shopOrderVo.setThird(goods.getThird());

                SubmitChildOrderVo childOrderVo = initBuildSubmitChildOrderVo(goods, dto, o, s);

                GoodsSku goodsSku = goodsSkuService.loadByGoodsAndSkuHashCode(childOrderVo.getGoodsId(), s.getSkuHashCode());
                if (goodsSku == null) {
                    //如果商品规格不存在,报错
                    throw new RRException(GoodsExceptionEnum.PRODUCT_SKU_NOT_EXISTS);
                }
                ProductSingleGoodsEntity singleGoods = goodsSku.loadSingleGoods();
                if (singleGoods == null) {
                    //库存不存在
                    throw new RRException(GoodsExceptionEnum.SINGLE_GOODS_STOCK_NOT_EXISTS);
                }

                childOrderVo.setAreaFeature(goods.getAreaFeature());
                childOrderVo.setSkuHashCode(s.getSkuHashCode());
                childOrderVo.setSkuSetName(goodsSku.getSkuSetName());
                childOrderVo.setSkuBarCode(goodsSku.getBarCode());
                if (StringUtils.isNotBlank(goodsSku.getCover())) {
                    childOrderVo.setGoodsCover(goodsSku.getCover());
                }
                childOrderVo.setSingleGoodsId(singleGoods.getId());
                childOrderVo.setSingleGoodsCode(singleGoods.getCode());
                childOrderVo.setSingleGoodsTitle(singleGoods.getTitle());
                childOrderVo.setUnit(singleGoods.getUnit());
                childOrderVo.setThirdSkuId(goodsSku.getThirdSkuId());

                //显示库存的情况=====================================
                if (s.getNum() <= singleGoods.getAbleStock()) {
                    //0库存足够
                    childOrderVo.setStockStatus(0);
                    //2库存紧张
                    if (singleGoods.getAbleStock() < 10) {
                        childOrderVo.setStockStatus(2);
                    }

                } else {
                    //1库存不足
                    childOrderVo.setStockStatus(1);
                }

                // 判断是否为第三方候鸟商品
                if (goods.getThird() && 99 == goods.getSource()) {
                    shopOrderVo.setSource(goods.getSource());
                    shopOrderVo.setHouniaoSpuId(goods.getHouniaoSpuId());

                    JSONObject jsonObject = new JSONObject();
                    jsonObject.put("sku_id", goodsSku.getThirdSkuId());
                    jsonObject.put("goods_num", s.getNum());
                    houniaoGoods.add(jsonObject);

                    /**
                     * 获取商品税率
                     */
                    JSONObject req2 = new JSONObject();
                    req2.put("goods_spu", goods.getHouniaoSpuId());
                    JSONObject json = houniaoApiUtil.client(req2, HouniaoConstant.GOODS_SPEC_PRICE.getUrl());
//                    System.out.println("json.toJSONString() = " + json.toJSONString());
                    BigDecimal taxRate = new BigDecimal(json.getJSONObject("data").getJSONArray("sku_list").getJSONObject(0).getString("tax_rate"));                    BigDecimal price = goods.getMinSalePrice();
//                    BigDecimal taxRate = new BigDecimal(9.1);
//                    System.out.println("taxRate = " + taxRate);
//                    System.out.println("goods.getMinSalePrice() = " + goods.getMinSalePrice());
                    BigDecimal dividedBy100 = taxRate.divide(new BigDecimal(100));
                    BigDecimal result = dividedBy100.multiply(goods.getMinSalePrice()).setScale(2, RoundingMode.CEILING);
//                    System.out.println("result = " + result);
                    shui.add(result);
                }

                //设置重量
                childOrderVo.setWeight(goodsSku.getWeight());
                childOrderVo.setTotalWeight(MathUtils.multiply(new BigDecimal(s.getNum()), goodsSku.getWeight()));
                //设总体积
                childOrderVo.setVolume(goodsSku.getVolume());
                childOrderVo.setTotalVolume(MathUtils.multiply(new BigDecimal(s.getNum()), goodsSku.getVolume()));
                //设总成本
                childOrderVo.setCost(singleGoods.getCostPrice());
                childOrderVo.setTotalCost(MathUtils.multiply(new BigDecimal(s.getNum()), singleGoods.getCostPrice()));
                //首单优惠分摊
                childOrderVo.setFirstOrderReduced(BigDecimal.ZERO);
                //计算会员的折扣
                // BigDecimal discount = goodsService.getUserGoodsDiscount(userId, goods);

                //设置折扣后的价格
//                if ((discount.compareTo(BigDecimal.TEN) < 0) && (discount.compareTo(BigDecimal.ZERO) > 0)) {
//                    childOrderVo.setDiscount(discount.toString());
//                    //折扣价
//                    childOrderVo.setFactPrice(MathUtils.multiplyMulti(2, goodsSku.getSalePrice(), discount, new BigDecimal("0.1")));
//                    childOrderVo.setSalePrice(goodsSku.getSalePrice());
//                    childOrderVo.setTotalReduced(MathUtils.multiply(MathUtils.subtract(childOrderVo.getSalePrice(), childOrderVo.getFactPrice()), new BigDecimal(s.getNum())));
//                } else {
//                    childOrderVo.setFactPrice(goodsSku.getSalePrice());
//                    childOrderVo.setSalePrice(goodsSku.getSalePrice());
//                    childOrderVo.setTotalReduced(BigDecimal.ZERO);
//                }
                childOrderVo.setFactPrice(goodsSku.getSalePrice());
                childOrderVo.setSalePrice(goodsSku.getSalePrice());
                childOrderVo.setTotalReduced(BigDecimal.ZERO);

                childOrderVo.setExchangePoint(BigDecimal.ZERO);

                childOrderVo.setMarketPrice(goods.getMaxMarketPrice());
                childOrderVo.setGiveBackPoint(goods.getGivePoint());
                childOrderVo.setTotalGiveBackPoint(MathUtils.multiply(goods.getGivePoint(),new BigDecimal(s.getNum())));
                //TODO:候鸟API 统一加价，同时有1:1贡献值

                if (goods.getThird() && 99 == goods.getSource()) {
                    childOrderVo.setConsumptionValue(goodsSku.getSalePrice());
                    childOrderVo.setTotalConsumptionValue(MathUtils.setScale(goodsSku.getSalePrice().doubleValue() * s.getNum()));
                } else {
                    childOrderVo.setConsumptionValue(goods.getConsumptionValue());
                    childOrderVo.setTotalConsumptionValue(MathUtils.setScale(goods.getConsumptionValue().doubleValue() * s.getNum()));
                }

                childOrderVo.setTotalPrice(MathUtils.multiply(childOrderVo.getFactPrice(), new BigDecimal(s.getNum())));
                childOrderVo.setTotalFactPrice(childOrderVo.getTotalPrice());
                childOrderVo.setOriginalGoodsAmount(MathUtils.multiply(childOrderVo.getSalePrice(), new BigDecimal(s.getNum())));

                childOrderVo.setTotalPoint(BigDecimal.ZERO);
//                childOrderVo.setTotalPoint(MathUtils.multiply(goodsSku.getExchangePoint(),new BigDecimal(s.getNum())));

                return childOrderVo;
            }).collect(Collectors.toList());

            // 候鸟订单校验
            if (!houniaoGoods.isEmpty()) {
                List<HouniaoCheckDTO> list = new ArrayList<>();
                childOrderVoList.forEach(item -> {
                    HouniaoCheckDTO houniaoCheckDTO = new HouniaoCheckDTO();
                    houniaoCheckDTO.setGoods_num(item.getNum());
                    houniaoCheckDTO.setSku_id(String.valueOf(item.getThirdSkuId()));
                    houniaoCheckDTO.setGoods_spu(item.getHouniaoSpuId());
                    list.add(houniaoCheckDTO);
                });

                JSONArray jsonArray = new JSONArray();

                list.forEach( item -> {
                    JSONObject js = JSON.parseObject(JSONObject.toJSONString(item));
                    js = houniaoApiUtil.sortJsonObject(js);
                    jsonArray.add(js);
                });

                JSONObject checkGoods = new JSONObject();
                checkGoods.put("area_id", vo.getReceipt().getAreaCode());
                checkGoods.put("order_goods", jsonArray);

                try{
                    JSONObject checkGoodsRes = houniaoApiUtil.client(checkGoods, HouniaoConstant.CHECK_GOODS_ORDER_BATCH.getUrl());
                    log.debug("商品渲染" + checkGoodsRes.toJSONString());
                    if (200 != checkGoodsRes.getInteger("code")) {
                        throw new RRException("可售检测：商品不可下单");
                    }
                }catch (Exception e){
                    throw new RRException("该地区暂时不发货");
                }

            }


            //每家店的订单商品总优惠
            BigDecimal totalReduced = MathUtils.setScale(childOrderVoList.stream().mapToDouble(c -> c.getTotalReduced().doubleValue()).sum());
            //每家店的商品总费用
            BigDecimal totalAmount = MathUtils.setScale(childOrderVoList.stream().mapToDouble(c -> c.getTotalPrice().doubleValue()).sum());

            shopOrderVo.setItems(childOrderVoList);

            // 候鸟费用校验
            if (!houniaoGoods.isEmpty()) {
                try {
                    JSONObject balanceReq = new JSONObject();

                    JSONObject balanceRes = houniaoApiUtil.client(balanceReq, HouniaoConstant.USERS_MONEY.getUrl());
                    log.debug("获取余额" + balanceReq.toJSONString());
                    BigDecimal userBalance = balanceRes.getJSONObject("data").getBigDecimal("usable_balance");
                    if (Objects.isNull(userBalance)) {
                        throw new RRException("商品不可下单");
                    }

                    if (userBalance.compareTo(totalAmount) < 0) {
                        // 这里对比候鸟余额与订单金额
                        throw new RRException("商品不可下单");

                    }
                } catch (Exception e) {
                    throw new RRException("商品不可下单");
                }

            }

            shopOrderVo.setAreaFeature(childOrderVoList.get(0).getAreaFeature());
            // 首单优惠出来之后这里还要加上首单优惠,同时还要分摊给每个子订单
            BigDecimal firstOrderReduced = BigDecimal.ZERO;
            Integer orderNum = orderService.getCountCommonOrder(shopOrderVo.getShopId(), userId);
            //如果没有下过普通订单，可以做首单优惠
            if (orderNum == 0) {
                FirstOrderActivity firstActivity = firstOrderActivityService.getByShopId(shopOrderVo.getShopId(), false);
                if (firstActivity != null) {
                    //如果满足首单优惠
                    if (totalAmount.compareTo(firstActivity.getFull()) > 0) {
                        shopOrderVo.setFirstOrderActivity(firstActivity);
                        firstOrderReduced = firstActivity.getReduction();
                        //开始计算首单优惠分摊=======================================
                        if (childOrderVoList.size() == 1) {
                            childOrderVoList.get(0).setFirstOrderReduced(firstOrderReduced);
                        } else {
                            BigDecimal sum = BigDecimal.ZERO;
                            //计算首单优惠分摊
                            for (SubmitChildOrderVo co : childOrderVoList) {
                                BigDecimal temp = MathUtils.setScaleDown(co.getTotalPrice().doubleValue() * firstOrderReduced.doubleValue() / totalAmount.doubleValue());
                                sum = MathUtils.add(temp, sum);
                                co.setFirstOrderReduced(temp);
                                co.setTotalFactPrice(MathUtils.subtract(co.getTotalFactPrice(),temp));

                            }
                            //如果出现少分摊的情况，要补回给第一个子订单
                            if (firstOrderReduced.compareTo(sum) > 0) {
                                BigDecimal value = MathUtils.subtract(firstOrderReduced, sum);
                                SubmitChildOrderVo submitChildOrderVo = childOrderVoList.get(0);
                                submitChildOrderVo.setFirstOrderReduced(MathUtils.add(submitChildOrderVo.getFirstOrderReduced(), value));
                                submitChildOrderVo.setTotalFactPrice(MathUtils.subtract(submitChildOrderVo.getTotalPrice(),submitChildOrderVo.getFirstOrderReduced()));
                            }
                        }

                    }
                }
            }
            shopOrderVo.setFirstOrderReduced(firstOrderReduced);

            //订单商品总价
            shopOrderVo.setTotalGoodsAmount(totalAmount);


//            /**
//             * 1、先计算得到系统推荐或选择的店铺优惠券
//             * 2、分摊到各商品子订单中
//             * 3、返回结果后再来记算店铺订单总价和店铺订单总优惠
//             */
//
//            computeSelectedShopCoupon(userId,shopOrderVo,o);
//
//            if(firstOrderReduced.compareTo(BigDecimal.ZERO)==0) {
//                commonOrderUseShopCouponService.handleShopCoupon(userId, shopOrderVo);
//            }
//            else
//            {
//                firstOrderUseShopCouponService.handleShopCoupon(userId, shopOrderVo);
//            }


            shopOrderVo.setTotalReduced(MathUtils.addMulti(totalReduced, firstOrderReduced,shopOrderVo.getShopCoupon().getCouponResultValue()));
            //订单总成本
            shopOrderVo.setTotalCost(MathUtils.setScale(childOrderVoList.stream().mapToDouble(ss -> ss.getTotalCost().doubleValue()).sum()));

            //原商品总价
            shopOrderVo.setOriginalGoodsAmount(MathUtils.setScale(childOrderVoList.stream().mapToDouble(ss -> ss.getOriginalGoodsAmount().doubleValue()).sum()));

            //设算每家店的商品快递费用
            BigDecimal totalFreight = BigDecimal.ZERO;
            if (dto.getShipmentMode() == 0) {
                if (vo.getReceipt() != null) {
                    totalFreight = processFreight(o.getShopId(), vo.getReceipt(), childOrderVoList);
                }
            }

            // 候鸟快递
            BigDecimal houniaoFreight = BigDecimal.ZERO;
            if (!houniaoGoods.isEmpty()) {
                JSONObject req1 = new JSONObject();
                req1.put("area_id",vo.getReceipt().getAreaCode());
                req1.put("sku_data", houniaoGoods);
                JSONObject json = houniaoApiUtil.client(req1, HouniaoConstant.GET_FREIGHT_All.getUrl());
                BigDecimal b = json.getJSONObject("data").getBigDecimal("total_freight");
                for (int i = 0; i < shui.size(); i++) {
                    b = b.add(shui.get(i));
                }
                houniaoFreight = houniaoFreight.add(b);
            }
            totalFreight = totalFreight.add(houniaoFreight);
            //订单运费
            shopOrderVo.setTotalFreight(totalFreight);

            //不含运费，扣出首单，没扣除优惠券的费用
            shopOrderVo.setTotalAmountNoCoupon(MathUtils.setScale(totalAmount.doubleValue() - firstOrderReduced.doubleValue()));

            //不含运费,扣出首单，扣除店铺优惠券的费用
            shopOrderVo.setTotalAmountNoFreight(MathUtils.setScale(shopOrderVo.getTotalAmountNoCoupon().doubleValue() - shopOrderVo.getShopCoupon().getCouponResultValue().doubleValue()));

            //不含运费，扣出首单，扣除店铺优惠券的费用
            shopOrderVo.setTotalAmountDecShopCoupon(shopOrderVo.getTotalAmountNoFreight());

            //不含运费，扣出首单，扣除店铺优惠券的费用,扣出平台抵扣积分
            shopOrderVo.setTotalAmountDecPlatformPoint(shopOrderVo.getTotalAmountNoFreight());

            //订单总费用（加了运费）
            shopOrderVo.setTotalAmount(MathUtils.add(shopOrderVo.getTotalAmountNoFreight() ,totalFreight));

            //订单商品总数
            shopOrderVo.setGoodsNum(childOrderVoList.stream().mapToInt(SubmitChildOrderVo::getNum).sum());

            //可赠送积分
            shopOrderVo.setTotalGiveBackPoint(MathUtils.setScale(childOrderVoList.stream().mapToDouble(c -> c.getTotalGiveBackPoint().doubleValue()).sum()));
            //总共需要赠送多少贡献值
            shopOrderVo.setTotalConsumptionValue(MathUtils.setScale(childOrderVoList.stream().mapToDouble(t -> t.getTotalConsumptionValue().doubleValue()).sum()));


            //需要使用的积分
//            shopOrderVo.setTotalPoint(MathUtils.setScale(childOrderVoList.stream().mapToDouble(c -> c.getTotalPoint().doubleValue()).sum()));
            shopOrderVo.setTotalPoint(BigDecimal.ZERO);
            shopOrderVo.setPointGoods(false);
//            shopOrderVo.setPointGoods(shopOrderVo.getTotalPoint().compareTo(BigDecimal.ZERO)>0);
            shopOrderVo.setExchange(false);
            return shopOrderVo;
        }).collect(Collectors.toList());
    }


    /**
     * 创建订单的钥匙
     *
     * @param order
     */
    @Override
    public void createOrderKey(Order order) {
        createOrderService.createOrderKey(order);
    }

    /**
     * 创建收货地址或自提信息
     *
     * @param order
     * @param vo
     */
    @Override
    public void createOrderReceiving(Order order, SubmitOrderVo vo) {
        createOrderService.createOrderReceiving(order,vo);
    }


    /**
     * 创建订单
     *
     * @param userId
     * @param payOrder
     * @param submitOrderVo
     * @param vo
     * @return
     */
    @Override
    public Order createOrder(Long userId, PayOrder payOrder, SubmitOrderVo submitOrderVo, SubmitShopOrderVo vo) {
        return createOrderService.createOrder(userId,payOrder,submitOrderVo,vo);
    }


    /**
     * 计算一个店铺下的订单的所有商品的运费合计
     *
     * @param shopId
     * @param receipt
     * @param childOrderVoList
     * @return
     */
    @Override
    public BigDecimal processFreight(Long shopId, SubmitOrderReceiptVo receipt, List<SubmitChildOrderVo> childOrderVoList) {
        return createOrderService.processFreight(shopId,receipt,childOrderVoList);
    }


}
